package com.baicaoyuan.web;


import com.baicaoyuan.web.common.FastJsonUtils;
import com.baicaoyuan.web.common.LogUtil;
import com.baicaoyuan.web.common.Status;
import com.baicaoyuan.web.common.annotation.MemberAccess;
import com.baicaoyuan.web.common.exception.StateMessage;
import com.baicaoyuan.web.request.BaseRequest;
import com.baicaoyuan.web.service.UserService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @author 罗富祥s
 */
@Aspect
@Component
public class SecurityAop {
    @Autowired
    UserService userService;

    /*
     * 定义一个切入点
     */
    @Pointcut("execution(* com.baicaoyuan.web.controller.*Controller.*(..))")
    public void executeService() {
    }


    @Around("executeService()")
    private Object checkBaseToken(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Signature sig = proceedingJoinPoint.getSignature();
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }

        MethodSignature methodSignature = (MethodSignature) sig;
        Object target = proceedingJoinPoint.getTarget();
        Method currentMethod = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());

        //方法上有该标记
        Annotation methodAnnotation = currentMethod.getAnnotation(MemberAccess.class);
        if (methodAnnotation != null) {
            Status status = this.checkSession(proceedingJoinPoint);
            if (!status.getState()) {
                return status;
            }
        } else {
            Object[] args = proceedingJoinPoint.getArgs();

            String params = FastJsonUtils.object2JsonString(args);
            // 从参数列表中获取参数对象
            String signature = proceedingJoinPoint.getSignature().getName();
            LogUtil.Info(String.format("{ 无@MemberAccess权限操作： %s， 输入参数： %s}", signature, params));
        }
        return proceedingJoinPoint.proceed();
    }

    private Status checkSession(ProceedingJoinPoint proceedingJoinPoint) {

        Object[] args = proceedingJoinPoint.getArgs();
        String params = FastJsonUtils.object2JsonString(args);
        // 从参数列表中获取参数对象
        String signature = proceedingJoinPoint.getSignature().getName();
        for (Object obj : args) {
            if (obj instanceof BaseRequest) {
                BaseRequest baseReq = (BaseRequest) obj;
                String token = baseReq.getToken();
                if (token == null || "".equals(token.trim())) {
                    return new Status(StateMessage.TOKEN_NO);
                }
                try {
                    boolean b = userService.checkToken(baseReq.getUserId(), baseReq.getToken());
                    if (!b) {
                        return new Status(StateMessage.TOKEN_ERROR);
                    }
                    LogUtil.Info(String.format("{ 用户id：%s，用户登入端：%s, 操作： %s， 输入参数： %s}", baseReq.getUserId(), baseReq.getClient(), signature, params));
                    return new Status(StateMessage.SUCCESS);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }
        return new Status(StateMessage.TOKEN_ERROR);
    }
}
